#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
数据库创建功能模块
提供数据库文件创建、配置更新和初始化等功能
"""

import os
import json
import subprocess
import sys
from PyQt5.QtWidgets import QFileDialog, QMessageBox, QApplication
from db_utils import DatabaseUtils
from config_utils import ConfigManager
from logger_module import log_info, log_error

class DatabaseCreator:
    """
    数据库创建器类，负责创建新数据库、更新配置和初始化
    """
    
    @staticmethod
    def create_new_database(parent_widget=None, source_db_path=None):
        """
        创建新的数据库文件并从当前数据库复制结构
        
        Args:
            parent_widget: 父窗口组件，用于显示对话框
            source_db_path: 可选，源数据库路径（已弃用）
            
        Returns:
            tuple: (success, message) - (是否成功, 消息内容)
        """
        try:
            # 获取当前应用程序
            app = QApplication.instance()
            if not app:
                app = QApplication([])
            
            # 自动使用当前配置的数据库作为源数据库
            if not source_db_path:
                # 从配置文件获取当前数据库路径
                current_db_path = ConfigManager.get_database_path()
                if not current_db_path or not os.path.exists(current_db_path):
                    error_msg = "无法获取当前数据库路径或数据库文件不存在"
                    log_error(error_msg)
                    QMessageBox.critical(parent_widget, "错误", error_msg)
                    return False, error_msg
                source_db_path = current_db_path
            
            # 显示保存文件对话框，让用户选择新数据库文件的位置和名称
            db_path, _ = QFileDialog.getSaveFileName(
                parent_widget,
                "创建新数据库",
                os.path.join(os.getcwd(), "New_Contract.db"),
                "数据库文件 (*.db);;所有文件 (*)"
            )
            
            # 如果用户取消选择，返回取消信息
            if not db_path:
                return False, "数据库创建已取消"
            
            # 确保文件扩展名为.db
            if not db_path.lower().endswith('.db'):
                db_path += '.db'
            
            # 检查文件是否已存在
            if os.path.exists(db_path):
                reply = QMessageBox.warning(
                    parent_widget,
                    "确认覆盖",
                    f"数据库文件 '{os.path.basename(db_path)}' 已存在，是否覆盖？",
                    QMessageBox.Yes | QMessageBox.No,
                    QMessageBox.No
                )
                if reply != QMessageBox.Yes:
                    return False, "数据库创建已取消"
            
            # 确保目录存在
            db_dir = os.path.dirname(db_path)
            if db_dir and not os.path.exists(db_dir):
                try:
                    os.makedirs(db_dir)
                    log_info(f"创建数据库目录: {db_dir}")
                except Exception as e:
                    error_msg = f"创建数据库目录失败: {str(e)}"
                    log_error(error_msg)
                    QMessageBox.critical(parent_widget, "错误", error_msg)
                    return False, error_msg
            
            # 从现有数据库复制结构
            success, results = DatabaseUtils.create_database_from_existing(source_db_path, db_path)
            
            if not success:
                error_msg = "从现有数据库复制结构失败！"
                log_error(error_msg)
                log_error("\n".join(results))
                # 显示错误详情
                details = "\n".join(results)
                QMessageBox.critical(parent_widget, "创建失败", f"{error_msg}\n\n详情:\n{details}")
                return False, error_msg
            
            # 更新配置文件中的数据库路径
            config_success = ConfigManager.set_database_path(db_path)
            if config_success:
                # 通知用户设置已保存
                log_info(f"数据库路径已更新到配置文件: {db_path}")
                
                # 显示成功消息
                # 显示成功消息
                success_msg = f"数据库 '{os.path.basename(db_path)}' 已成功创建（从现有数据库复制结构）！"
                QMessageBox.information(
                    parent_widget,
                    "创建成功",
                    f"{success_msg}\n\n数据库路径: {db_path}\n\n程序将自动重启并打开用户登录窗口...\n\n【登录新的数据库，用户名：admin,密码：admin】"
                )
                
                # 重启程序并打开登录窗口
                log_info(f"准备重启程序以应用新的数据库配置")
                
                # 获取当前Python解释器路径和当前脚本路径
                python_exe = sys.executable
                main_script = sys.argv[0]
                
                # 在新进程中启动程序
                subprocess.Popen([python_exe, main_script])
                
                # 关闭当前应用程序
                app = QApplication.instance()
                if app:
                    app.quit()
                
                return True, success_msg
            else:
                # 配置更新失败但数据库创建成功
                warning_msg = "数据库创建成功，但配置更新失败！"
                log_error(warning_msg)
                QMessageBox.warning(
                    parent_widget,
                    "部分成功",
                    f"{warning_msg}\n\n数据库已创建在: {db_path}\n但配置未更新，您需要手动重启程序并重新选择此数据库。"
                )
                return False, warning_msg
                
        except Exception as e:
            error_msg = f"创建数据库时发生未知错误: {str(e)}"
            log_error(error_msg)
            QMessageBox.critical(parent_widget, "错误", error_msg)
            return False, error_msg
    
    @staticmethod
    def validate_database_path(db_path):
        """
        验证数据库路径是否有效
        
        Args:
            db_path (str): 数据库文件路径
            
        Returns:
            tuple: (valid, message) - (是否有效, 消息内容)
        """
        # 检查路径长度
        if len(db_path) > 260:  # Windows路径长度限制
            return False, "数据库路径过长，请选择更短的路径"
        
        # 检查是否包含非法字符
        invalid_chars = ['<', '>', ':', '"', '/', '\\', '|', '?', '*']
        if any(char in db_path for char in invalid_chars):
            return False, "数据库路径包含非法字符"
        
        # 检查磁盘空间
        try:
            drive = os.path.splitdrive(db_path)[0]
            free_bytes = os.statvfs(drive)[0] * os.statvfs(drive)[3] if drive else 0
            if free_bytes < 100 * 1024 * 1024:  # 小于100MB
                return False, "磁盘空间不足，建议至少保留100MB可用空间"
        except:
            pass  # 忽略磁盘空间检查错误
        
        return True, "路径有效"